//
//  HJConversationManager.m
//  KaiChat
//
//  Created by lx on 2023/10/20.
//

#import "HJConversationManager.h"
#import "HJWebSocketManager.h"
#import "HJChatSessionModel.h"
#import "HJChatMessageModel.h"
#import "HJChatUserModel.h"
#import "HJChatGroupModel.h"
#import "HJIM.h"
#import "HJMessageFileManager.h"

@interface HJConversationManager()

@property (nonatomic, assign) NSInteger allMessageUnReadCount;


@end

@implementation HJConversationManager

- (void)addConversation:(HJChatSessionModel *)sessionModel addNot:(BOOL)addNot {
    if (sessionModel.chatType == HJChatTypeSingle || sessionModel.chatType == HJChatTypeGroup || sessionModel.chatType == HJChatTypeSystem) {
        if (isEmptyString(sessionModel.sessionId) || sessionModel.sessionId.intValue == 0) return;
    }
    HJChatSessionModel *obj = [self getConversationBySessionId:sessionModel.sessionId];
    if (obj) {
        sessionModel.isTop = obj.isTop;
        sessionModel.isMute = obj.isMute;
        if (sessionModel.chatType == HJChatTypeGroup) {
            sessionModel.hasNotice = obj.hasNotice;
        }
        sessionModel.unReadCount = toString(@(sessionModel.unReadCount.integerValue + obj.unReadCount.integerValue));
    }
    
   [sessionModel bg_saveOrUpdate];
    if (addNot) {
        [[NSNotificationCenter defaultCenter] postNotificationName:updateConversationNotification object:sessionModel];
    }
}

- (void)addConversation:(HJChatSessionModel *)sessionModel {
    [self addConversation:sessionModel addNot:YES];
}

- (void)deleteConversationWithSessionId:(NSString *)sessionId completion:(void (^ _Nullable)(NSError * _Nonnull))completion {
    NSString *sql = [NSString stringWithFormat:@"where %@=%@",bg_sqlKey(@"sessionId"), bg_sqlValue(sessionId)];
    [HJChatSessionModel bg_deleteAsync:[HJChatSessionModel bg_tableName] where:sql complete:^(BOOL isSuccess) {
        [HJMessageFileManager deleteFileWithSessionId:sessionId];
        [HJChatMessageModel bg_drop:[HJChatMessageModel bg_tableNameWithSessionId:sessionId]];
        [HJChatGroupModel bg_delete:[HJChatGroupModel bg_tableName] where:[NSString stringWithFormat:@"where %@=%@", bg_sqlKey(@"groupId"),bg_sqlValue(sessionId)]];
        [self updateBadge];
        dispatch_async_main_queue(^{
            if (completion) {
                completion(isSuccess ? nil : [NSError errorWithCode:-10010]);
            }
        });
    }];
}
 
- (void)allConversationListCompletion:(void (^__nullable)(NSArray *list))completion {
    NSString * where = [NSString stringWithFormat:@"where %@ != 0",bg_sqlKey(@"sessionId")];
    [HJChatSessionModel bg_findAsync:[HJChatSessionModel bg_tableName] where:where complete:^(NSArray * _Nullable array) {
        
        for (HJChatSessionModel *sessionModel in array) {
            if (isEmptyString(sessionModel.content)) {
                HJChatMessageModel *lastMessageModel = [HJIM.shareIM.messageManager getSessionLastMessagesBySessionId:sessionModel.sessionId];
                if (lastMessageModel) {
                    sessionModel.content = lastMessageModel.content;
                    sessionModel.timestamp = lastMessageModel.timestamp;
                    [sessionModel bg_saveOrUpdate];
                }
            }
        }
        
        if (completion) {
            completion(array);
        }
    }];
}

- (void)getConversationBySessionId:(NSString *)sessionId completion:(void (^__nullable)(HJChatSessionModel *sessionModel))completion {
    
    NSString *sql = [NSString stringWithFormat:@"where %@=%@",bg_sqlKey(@"sessionId"), bg_sqlValue(sessionId)];
    [HJChatSessionModel bg_findAsync:[HJChatSessionModel bg_tableName] where:sql complete:^(NSArray * _Nullable array) {
        
        HJChatSessionModel *sessionModel = array.lastObject;
        
        if (sessionModel) {
            NSString *tableName = [HJChatMessageModel bg_tableNameWithSessionId:sessionId];
            HJChatMessageModel *lastMessageModel = [HJChatMessageModel bg_find:tableName limit:1 orderBy:@"timestamp" desc:YES].lastObject;
            if (!lastMessageModel) {
                sessionModel.content = @"";
                sessionModel.senderId = @"";
                sessionModel.messageType = -1;
                [sessionModel bg_saveOrUpdate];
            } else {
                sessionModel.content = lastMessageModel.content;
                if (lastMessageModel.messageType > 0) {
                    sessionModel.messageType = lastMessageModel.messageType;
                }
                sessionModel.timestamp = lastMessageModel.timestamp;
                sessionModel.senderId = lastMessageModel.senderId;
            }
            completion(sessionModel);
        } else {
            completion(nil);
        }
    }];
}

- (HJChatSessionModel *)getSimpleConversationBySessionId:(NSString *)sessionId {
    return [HJChatSessionModel bg_find:[HJChatSessionModel bg_tableName] where:[NSString stringWithFormat:@"where %@=%@",bg_sqlKey(@"sessionId"), bg_sqlValue(sessionId)]].lastObject;;
}

- (HJChatSessionModel *)getConversationBySessionId:(NSString *)sessionId {
    NSString *sql = [NSString stringWithFormat:@"where %@=%@",bg_sqlKey(@"sessionId"), bg_sqlValue(sessionId)];
    NSString *tableName = [HJChatMessageModel bg_tableNameWithSessionId:sessionId];
    HJChatSessionModel *sessionModel = [HJChatSessionModel bg_find:[HJChatSessionModel bg_tableName] where:sql].lastObject;
    if (sessionModel) {
        HJChatMessageModel *lastMessageModel = [HJChatMessageModel bg_find:tableName limit:1 orderBy:@"timestamp" desc:YES].lastObject;
        if (!lastMessageModel) {
            sessionModel.content = @"";
            sessionModel.senderId = @"";
            sessionModel.messageType = -1;
            [sessionModel bg_saveOrUpdate];
        } else {
            sessionModel.content = lastMessageModel.content;
            if (lastMessageModel.messageType > 0) {
                sessionModel.messageType = lastMessageModel.messageType;
            }
            sessionModel.timestamp = lastMessageModel.timestamp;
            sessionModel.senderId = lastMessageModel.senderId;
        }
    }
    return sessionModel;
}

- (BOOL)isNewConversationBySessionId:(NSString*)sessionId {
    NSString *where = [NSString stringWithFormat:@"where %@=%@",bg_sqlKey(@"sessionId"), bg_sqlValue(sessionId)];
    return [HJChatSessionModel bg_count:[HJChatSessionModel bg_tableName] where:where] == 0;
}

- (void)updateBadge {
    //    NSString * where = [NSString stringWithFormat:@"where %@ is not null",bg_sqlKey(@"sessionId")];
    [HJChatSessionModel bg_findAllAsync:[HJChatSessionModel bg_tableName] complete:^(NSArray * _Nullable array) {
        NSInteger totalCount = 0;
        for (HJChatSessionModel *sessionModel in array) {
            if (sessionModel.chatType == HJChatTypeSingle || sessionModel.chatType == HJChatTypeGroup) {
                if (!sessionModel.isMute.boolValue) {
                    totalCount += sessionModel.unReadCount.integerValue;
                }
            }
        }
        dispatch_async_main_queue(^{
            [[NSNotificationCenter defaultCenter] postNotificationName:messageBadgeChangeNotification object:@(totalCount)];
        });
    }];
}

- (void)updateOfficialConversation {
    
    [HJNetworking.shareNetwork GET:API_officialList parameters:nil success:^(NSDictionary * _Nonnull responseObject, id  _Nonnull data) {
        
        NSArray *list = data[@"list"];
        if (![list isKindOfClass:NSArray.class]) return;
        
        [NSUserDefaults.standardUserDefaults setValue:list forKey:@"officialList"];
        
        for (NSDictionary *dict in list) {
            NSInteger Id = [dict[@"id"] integerValue];
            HJChatSessionModel *sessionModel = [[HJChatSessionModel alloc] init];
            sessionModel.chatType = HJChatTypeOfficial;
            if (Id == KaiPaySessionId) {
                sessionModel.officialType = HJChatOfficialTypeKaiPay;
            } else if (Id == KaiNewsSessionId) {
                sessionModel.officialType = HJChatOfficialTypeKaiNews;
            } else if (Id == KaiSupportSessionId) {
                sessionModel.officialType = HJChatOfficialTypeKaiSupport;
            }
            sessionModel.sessionId = getOfficiaSessionId(dict[@"id"]);
            sessionModel.isTop = toString(dict[@"is_top"]);
            sessionModel.isMute = toString(dict[@"is_mute"]);
            sessionModel.sessionName = dict[@"name"];
            sessionModel.sessionAvatar = dict[@"img"];
            
            HJChatSessionModel *currentSessionModel = [HJIM.shareIM.conversationManager getConversationBySessionId:sessionModel.sessionId];
            if (currentSessionModel) {
                if (![sessionModel.isTop isEqualToString:currentSessionModel.isTop] || ![sessionModel.isMute isEqualToString:currentSessionModel.isMute]) {
                    currentSessionModel.isTop = sessionModel.isTop;
                    currentSessionModel.isMute = sessionModel.isMute;
                    [currentSessionModel bg_saveOrUpdateAsync:^(BOOL isSuccess) {
                        dispatch_async_main_queue(^{
                            [[NSNotificationCenter defaultCenter] postNotificationName:updateConversationInfoNotification object:currentSessionModel];
                        });
                    }];
                }
            }
        }
    } failure:^(NSError * _Nonnull error) {
        
    }];
}

- (void)getUnreadConversationMessageIds:(NSString *)sessionId completion:(void (^__nullable)(NSArray *list))completion {
    
    NSString *where = [NSString stringWithFormat:@"where %@=%@",bg_sqlKey(@"sessionId"), bg_sqlValue(sessionId)];
    [HJChatSessionModel bg_findAsync:[HJChatSessionModel bg_tableName] where:where complete:^(NSArray * _Nullable array) {
    
        HJChatSessionModel *sessionModel = array.firstObject;
        if (sessionModel.unReadCount.intValue == 0) {
            if (completion) {
                completion(nil);
            }
            return;
        };
        
        NSArray *messageModels = [HJChatMessageModel bg_find:[HJChatMessageModel bg_tableNameWithSessionId:sessionId] limit:sessionModel.unReadCount.intValue orderBy:@"timestamp" desc:YES];
        
        NSMutableArray *msgIds = [NSMutableArray array];
        for (HJChatMessageModel *model in messageModels) {
            if (model.serverMsgId) {
                [msgIds addObject:model.serverMsgId];
            }
        }
        if (completion) {
            completion(msgIds);
        }
    }];
}

- (void)topWithSessionId:(NSString *)sessionId isTop:(BOOL)isTop type:(HJChatType)type complete:(void (^__nullable)(NSError *error))complete {
    if ([sessionId isEqualToString:HJUserInfo.userId]) {
        !complete ?: complete(nil);
        return;
    }
    
    NSInteger session_type = 0;
    if (type == HJChatTypeSingle) {
        session_type = 1;
    } else if (type == HJChatTypeGroup) {
        session_type = 2;
    } else if (type == HJChatTypeOfficial) {
        session_type = 3;
    }
    
    NSString *session_id = sessionId;
    if (type == HJChatTypeOfficial) {
        session_id = getOfficialRealSessionId(sessionId);
    }
    
    TJLog(@"sessionId = %@, HJUserInfo.userId = %@", session_id, HJUserInfo.userId);
    [HJNetworking.shareNetwork POSTBodyJSON:API_sessionTop parameters:@{
        @"session_id": session_id,
        @"is_top": isTop ? @1 : @0,
        @"session_type": @(session_type)
    } success:^(NSDictionary * _Nonnull responseObject, id  _Nonnull data) {
        !complete ?: complete(nil);
    } failure:^(NSError * _Nonnull error) {
        !complete ?: complete(error);
    }];
}


- (void)muteWithSessionId:(NSString *)sessionId isMute:(BOOL)isMute type:(HJChatType)type complete:(void (^__nullable)(NSError *error))complete {
    
    NSInteger session_type = 0;
    if (type == HJChatTypeSingle) {
        session_type = 1;
    } else if (type == HJChatTypeGroup) {
        session_type = 2;
    } else if (type == HJChatTypeOfficial) {
        session_type = 3;
    }
    
    NSString *session_id = sessionId;
    if (type == HJChatTypeOfficial) {
        session_id = getOfficialRealSessionId(sessionId);
    }
    
    TJLog(@"sessionId = %@, HJUserInfo.userId = %@", session_id, HJUserInfo.userId);
    [HJNetworking.shareNetwork POSTBodyJSON:API_sessionMute parameters:@{
        @"session_id": session_id,
        @"is_mute": isMute ? @1 : @0,
        @"session_type": @(session_type)
    } success:^(NSDictionary * _Nonnull responseObject, id  _Nonnull data) {
        !complete ?: complete(nil);
    } failure:^(NSError * _Nonnull error) {
        !complete ?: complete(error);
    }];
}



- (void)loadConversatioInfoWithSessionId:(NSString *)sessionId type:(HJChatType)type completion:(void (^__nullable)(HJChatSessionModel *sessionModel))completion {
    
    NSInteger session_type = 0;
    if (type == HJChatTypeSingle) {
        session_type = 1;
    } else if (type == HJChatTypeGroup) {
        session_type = 2;
    } else if (type == HJChatTypeOfficial) {
        session_type = 3;
    }
    
    NSString *session_id = sessionId;
    if (type == HJChatTypeOfficial) {
        session_id = getOfficialRealSessionId(sessionId);
    }
    
    [HJNetworking.shareNetwork POSTBodyJSON:API_sessionInfo parameters:@{
        @"session_id": session_id,
        @"chat_type": @(session_type)
    } success:^(NSDictionary * _Nonnull responseObject, id  _Nonnull data) {

        HJChatSessionModel *sessionModel = [[HJChatSessionModel alloc] init];
        sessionModel.sessionId = sessionId;
        sessionModel.chatType = type;
        sessionModel.sessionName = toString(data[@"session_name"]);
        sessionModel.sessionAvatar = toString(data[@"session_image"]);
        sessionModel.sessionUserd = toString(data[@"other_id"]);;
        sessionModel.sessionUid = toString(data[@"no"]);;
        if ([data[@"is_top"] intValue] == 1) {
            sessionModel.isTop = @"1";
        } else {
            sessionModel.isTop = @"0";
        }
        
        if ([data[@"is_mute"] intValue] == 1) {
            sessionModel.isMute = @"1";
        } else {
            sessionModel.isMute = @"0";
        }
        !completion ?: completion(sessionModel);
    } failure:^(NSError * _Nonnull error) {
        !completion ?: completion(nil);
    }];
}


- (void)readMessageWithSessionId:(nullable NSString *)sessionId msgIds:(nullable NSArray *)msgIds completion:(void (^ _Nullable )( NSError * _Nullable error))completion {
    
    [self getConversationBySessionId:sessionId completion:^(HJChatSessionModel * _Nonnull sessionModel) {
        
        if (sessionModel.unReadCount.intValue <= 0) return;
        
        sessionModel.unReadCount = @"0";
        BOOL res = [sessionModel bg_saveOrUpdate];
        NSLog(@"res = %d", res);
        
        [[NSNotificationCenter defaultCenter] postNotificationName:updateConversationInfoNotification object:sessionModel];
        [HJIM.shareIM.conversationManager updateBadge];
        
        if (!msgIds) {
            [self readMessageWithType:sessionModel.chatType sessionId:sessionId msgIds:msgIds completion:completion];
        } else {
            [HJIM.shareIM.conversationManager getUnreadConversationMessageIds:sessionId completion:^(NSArray * _Nonnull list) {
                [self readMessageWithType:sessionModel.chatType sessionId:sessionId msgIds:list completion:completion];
            }];
        }
    }];
}

- (void)readOfficialMessageWithSessionId:(nullable NSString *)sessionId {
    
    [self getConversationBySessionId:sessionId completion:^(HJChatSessionModel * _Nonnull sessionModel) {
        
        if (sessionModel.unReadCount.intValue <= 0) return;
        
        sessionModel.unReadCount = @"0";
        BOOL res = [sessionModel bg_saveOrUpdate];
        NSLog(@"res = %d", res);
        
        [[NSNotificationCenter defaultCenter] postNotificationName:updateConversationInfoNotification object:sessionModel];
        [HJIM.shareIM.conversationManager updateBadge];
    }];
}

- (void)readMessageWithType:(HJChatType)chatType sessionId:(nullable NSString *)sessionId msgIds:(NSArray *)msgIds completion:(void (^ _Nullable )( NSError * _Nullable error))completion {
    if (msgIds.count == 0) return;
    [HJNetworking.shareNetwork POSTBodyJSON:API_readMessage parameters:@{
        @"seq_ids": msgIds,
        @"session_id": sessionId
    } success:^(NSDictionary * _Nonnull responseObject, id  _Nonnull data) {
        !completion ?: completion(nil);
        NSLog(@"已读消息成功");
    } failure:^(NSError * _Nonnull error) {
        !completion ?: completion(error);
    }];
}

@end
